// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
// import crypto from 'crypto';

// 定义路由常量
const ROUTES = {
  PUBLIC: ['/login', '/api/auth/login', '/api/auth/logout', '/404', '/403'],
  PROTECTED: ['/home', '/sql', '/webrtc', '/webgl', '/vector', '/report', '/users', '/page1']
} as const;

export function middleware(req: NextRequest): NextResponse {
  try {
    // 确保nextUrl存在
    if (!req.nextUrl) {
      throw new Error('Request URL is not available');
    }
    
    const token = req.cookies.get('token')?.value;
    const { pathname } = req.nextUrl;
    
    // 生成nonce并设置CSP头部
    const { nonce, cspHeader } = generateCSPHeaders();
    const requestHeaders = new Headers(req.headers);
    requestHeaders.set('x-nonce', nonce);
    requestHeaders.set('Content-Security-Policy', cspHeader);

    // 检查路径类型的辅助函数
    const isPathPublic = (path: string): boolean => ROUTES.PUBLIC.some(p => path === p || path.startsWith(p + '/'));
    const isPathProtected = (path: string): boolean => ROUTES.PROTECTED.some(p => path === p || path.startsWith(p + '/'));
    
    const hasToken: boolean = !!token;
    
    // 创建统一的响应函数
    const createResponse = () => {
      const response = NextResponse.next({
        request: {
          headers: requestHeaders,
        },
      });
      response.headers.set('Content-Security-Policy', cspHeader);
      return response;
    };
    
    // 创建重定向响应函数
    const createRedirectResponse = (targetPath: string, originalReq: NextRequest) => {
      const redirectUrl = new URL(targetPath, originalReq.url);
      const response = NextResponse.redirect(redirectUrl);
      response.headers.set('Content-Security-Policy', cspHeader);
      return response;
    };
    
    // 路由处理逻辑
    // 根路径处理
    if (pathname === '/') {
      const redirectPath: string = hasToken ? '/home' : '/login';
      return createRedirectResponse(redirectPath, req);
    }
    
    // 受保护路径的访问控制
    if (!isPathPublic(pathname) && !hasToken && pathname !== '/') {
      const loginUrl = new URL('/login', req.url);
      loginUrl.searchParams.set('redirect', pathname);
      const response = NextResponse.redirect(loginUrl);
      response.headers.set('Content-Security-Policy', cspHeader);
      return response;
    }
    
    // 已登录用户访问登录页的重定向
    if (pathname === '/login' && hasToken) {
      return createRedirectResponse('/home', req);
    }
    
    // 正常请求处理
    return createResponse();
  } catch (error) {
    // 错误处理：记录错误并返回500响应
    console.error('Middleware error:', error);
    return createErrorResponse('Internal Server Error', 500);
  }
}

// 创建错误响应的辅助函数
function createErrorResponse(message: string, statusCode: number): NextResponse {
  return new NextResponse(message, {
    status: statusCode,
    headers: {
      'Content-Type': 'text/plain',
    },
  });
}

// 生成CSP头部和nonce的辅助函数
function generateCSPHeaders(): { nonce: string; cspHeader: string } {
  try {
    const nonce: string = Buffer.from(crypto.getRandomValues(new Uint8Array(16))).toString('base64');
    const cspHeader: string = `
      script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
      object-src 'none';
      base-uri 'none';
    `.replace(/\s{2,}/g, ' ').trim();
   console.log('nonce:', nonce);
    return { nonce, cspHeader };
  } catch (error) {
    console.error('Failed to generate CSP headers:', error);
    // 返回默认的安全头部配置作为备用
    return {
      nonce: '',
      cspHeader: "script-src 'self'; object-src 'none'; base-uri 'none';"
    };
  }
}

export const config = {
  matcher: ['/((?!_next|favicon.ico|static).*)'],
};
